// 实现这个项目的构建任务
const {src,dest,series,parallel,watch} = require('gulp');
const loadPlugins = require('gulp-load-plugins');
const bs = require('browser-sync').create();
const del = require('del');
const sass = require('sass');
const plugins = loadPlugins();

/**
 * 用于在调试或构建生产环境产物之前清空临时目录
 * @param cleanPath 要清空的目录
 * @returns {function(): *}
 */
const clean = (cleanPath='temp')=>{
  return function (){
    return del(cleanPath)
  }
}
/**
 * css 任务流，源码中的 scss 文件通过 sass 工具编译后输出到 temp 目录并重新加载开发服务器
 * @returns {*}
 */
const style = ()=>{
  return src('src/assets/styles/**',{base:'src'})
    .pipe(plugins.sass(sass)())
    .pipe(dest('temp'))
    .pipe(bs.reload({stream:true}))
}
/**
 * html 任务流，源码中的 html 文件通过对应模板工具编译后输出到 temp 目录并重新加载开发服务器
 * @returns {*}
 */
const pages = ()=>{
  const data = {
    menus: [
      {
        name: 'Home',
        icon: 'aperture',
        link: 'index.html'
      },
      {
        name: 'Features',
        link: 'features.html'
      },
      {
        name: 'About',
        link: 'about.html'
      },
      {
        name: 'Contact',
        link: '#',
        children: [
          {
            name: 'Twitter',
            link: 'https://twitter.com/w_zce'
          },
          {
            name: 'About',
            link: 'https://weibo.com/zceme'
          },
          {
            name: 'divider'
          },
          {
            name: 'About',
            link: 'https://github.com/zce'
          }
        ]
      }
    ],
    pkg: require('./package.json'),
    date: new Date()
  }
  return src('src/*.html',{base:'src'})
    .pipe(plugins.swig({data}))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream:true}))
}
/**
 * js 任务流，源码中的 js 文件通过 babel 工具编译后输出到 temp 目录并重新加载开发服务器
 * @returns {*}
 */
const script = ()=>{
  return src('src/assets/scripts/*.js',{base:'src'})
    .pipe(plugins.babel({presets:['@babel/preset-env']}))
    .pipe(dest('temp'))
    .pipe(bs.reload({stream:true}))
}

/**
 * 开发服务器
 * @returns {*}
 */
const serve = ()=>{
  // 开启任务之后注册对源码文件的监听
  watch('src/assets/styles/*.scss', style)
  watch('src/assets/scripts/*.js', script)
  // 对应文件改动之后开启对应的构建任务
  watch('src/*.html', pages)

  // 无需编译的静态文件改动后刷新开发服务器
  watch([
    'src/assets/images/**',
    'src/assets/fonts/**',
    'public/**'
  ],bs.reload)

  bs.init({
    port:8082,
    server: {
      baseDir: ['temp', 'src', 'public'],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  });
}

const build = ()=>{
  // 以 html 文件为入口，打到其中的依赖文件，并判断依赖文件类型，再做对应处理。
  return src('temp/*.html',{base:'temp'})
    .pipe(plugins.useref({searchPath:['temp','.']}))
    .pipe(plugins.if(/\.js$/,plugins.uglify()))
    .pipe(plugins.if(/\.css$/,plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/,plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest('dist'))
}

/**
 * 开启本地开发服务，洗清理目录，再进行一次文件编译，最后开启服务器
 */
const dev = series(clean(),parallel(style,pages,script),serve);



const image = () => {
  return src('src/assets/images/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const font = () => {
  return src('src/assets/fonts/**', { base: 'src' })
    .pipe(plugins.imagemin())
    .pipe(dest('dist'))
}

const extra = () => {
  return src('public/**', { base: 'public' })
    .pipe(dest('dist'))
}

const prod = series(
  clean('dist'),
  clean('temp'),
  parallel(style,pages,script,image,font,extra),
  build
);
lint = ()=> {
  return src(['**/*.js', '!node_modules/**'])
    .pipe(plugins.eslint({
      rules: {},
      globals: [ 'jQuery', '$' ],
      envs: [ 'browser' ]
    }))
    .pipe(plugins.eslint.formatEach('compact', process.stderr));
}



module.exports = {
 lint, dev,prod,clean:series(clean('temp'),clean('dist'))
}
